using AutoMapper;
using Bean.Entity;
using Bean.Entity.Attribute;
using Bean.Entity.Entities;
using Bean.Entity.Enum;
using Bean.Entity.Model;
using Bean.Infrastructure;
using Bean.Infrastructure.Extensions;
using Bean.Repository;
using Bean.Service.IService;
using Microsoft.Extensions.Logging;

namespace Bean.Service.Service;

/// <summary>
/// 
/// </summary>
public class PolicySysRuleInfoService : IPolicySysRuleInfoService, ITransientService
{
    private readonly ILogger<PolicySysRuleInfoService> _logger;

    private readonly IMapper _mapper;

    private IRepository<PolicySysRule> _policySysRuleRepository;
    private IRepository<Exhibit> _exhibitRepository;
    private IRepository<ServiceProviderInfo> _serviceProviderRepository;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="logger"></param>
    /// <param name="mapper"></param>
    /// <param name="policySysRuleRepository"></param>
    public PolicySysRuleInfoService(ILogger<PolicySysRuleInfoService> logger, IMapper
            mapper, IRepository<PolicySysRule> policySysRuleRepository, IRepository<Exhibit> exhibitRepository,
        IRepository<ServiceProviderInfo> serviceProviderRepository)
    {
        _logger = logger;
        _mapper = mapper;
        _policySysRuleRepository = policySysRuleRepository;
        _exhibitRepository = exhibitRepository;
        _serviceProviderRepository = serviceProviderRepository;
    }


    public async Task<List<PolicySysRuleInfoDto>> GetListAsync(List<long> ruleIds)
    {
        var list = new List<PolicySysRuleInfoDto>();
        if (!ruleIds.Any())
        {
            return list;
        }

        try
        {
            var ruleInfoList = await _policySysRuleRepository.AsQueryable()
                .Where(w => ruleIds.Contains(w.SysPolicyRuleId) && w.IsActive == 1)
                .ToListAsync();

            var policySysRuleInfoList = _mapper.Map<List<PolicySysRuleInfoDto>>(ruleInfoList);

            foreach (var ruleItem in policySysRuleInfoList)
            {
                var fareTypes = GetfaretFareTypes(ruleItem);
                var faretypeDic = GetFareTypesDic(fareTypes);
                var exhibitDic = new Dictionary<CIDEnum, List<Exhibit>>();

                // 获取有效的 exhibitIds
                var validExhibitIds = ruleItem.ActiveExhibit.Split(',')
                    .Select(id => long.TryParse(id, out long exhibitId) && exhibitId > 0 ? exhibitId : (long?)null)
                    .Where(id => id.HasValue)
                    .ToList();

                if (!validExhibitIds.Any())
                {
                    continue;
                }

                // 批量查询展位
                var exhibits = await _exhibitRepository.AsQueryable()
                    .Where(w => validExhibitIds.Contains(w.exhibitid))
                    .ToListAsync();

                if (!exhibits.Any())
                {
                    continue;
                }

                var spCodes = new HashSet<string>();

                foreach (var exhibitItem in exhibits)
                {
                    var serviceProvider = await _serviceProviderRepository.AsQueryable()
                        .FirstAsync(w => w.serviceproviderid == exhibitItem.SID);

                    if (serviceProvider != null && !string.IsNullOrEmpty(serviceProvider.serviceprovidercode))
                    {
                        spCodes.Add(serviceProvider.serviceprovidercode);

                        // 平台枚举
                        if (Enum.TryParse<CIDEnum>(serviceProvider.cid.ToString(), out CIDEnum cidEnum))
                        {
                            if (exhibitDic.ContainsKey(cidEnum))
                            {
                                exhibitDic[cidEnum].Add(exhibitItem);
                            }
                            else
                            {
                                exhibitDic[cidEnum] = [exhibitItem];
                            }
                        }
                    }
                }

                ruleItem.FareTypes = fareTypes;
                ruleItem.FareTypesDic = faretypeDic;
                ruleItem.SPCode = spCodes.ToList();
                ruleItem.ExhibitDic = exhibitDic;
            }

            return policySysRuleInfoList;
        }
        catch (Exception ex)
        {
            // 记录日志或返回适当的错误信息
            throw new InvalidOperationException("获取规则列表时发生错误", ex);
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ruleIds"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    // public async Task<List<PolicySysRuleInfoDto>> GetListAsync(List<long> ruleIds)
    // {
    //     var list = new List<PolicySysRuleInfoDto>();
    //     if (ruleIds.Count == 0)
    //     {
    //         return list;
    //     }
    //
    //     var ruleInfoList = await _policySysRuleRepository.AsQueryable()
    //         .Where(w => ruleIds.Contains(w.SysPolicyRuleId) && w.IsActive == 1)
    //         .ToListAsync();
    //
    //     var policySysRuleInfoList = _mapper.Map<List<PolicySysRuleInfoDto>>(ruleInfoList);
    //
    //     foreach (var ruleItem in policySysRuleInfoList)
    //     {
    //         var fareTypes = GetfaretFareTypes(ruleItem);
    //
    //         // var faretypeDic =
    //         //     new Dictionary<CIDEnum, List<PolicyFareTypeEnum>>();
    //
    //         var faretypeDic = GetFareTypesDic(fareTypes);
    //
    //
    //         var exhibitDic = new Dictionary<CIDEnum, List<Exhibit>>();
    //         // 
    //         var exhibitIds = ruleItem.ActiveExhibit.Split(",");
    //
    //         // 拿到对应的展位 
    //         var exhibits = await _exhibitRepository.AsQueryable()
    //             .Where(w => exhibitIds.Contains(w.exhibitid.ToString())).ToListAsync();
    //         var spCodes = new List<string>();
    //
    //         if (exhibits.Count == 0)
    //         {
    //             continue;
    //         }
    //
    //         foreach (var exhibitItem in exhibits)
    //         {
    //             if (exhibitItem.exhibitid <= 0)
    //             {
    //                 continue;
    //             }
    //
    //             var serviceProvider = await _serviceProviderRepository.AsQueryable()
    //                 .FirstAsync(w => w.serviceproviderid == exhibitItem.SID);
    //
    //             if (serviceProvider == null)
    //             {
    //                 continue;
    //             }
    //
    //             if (!spCodes.Contains(serviceProvider.serviceprovidercode))
    //             {
    //                 // 平台编码
    //                 spCodes.Add(serviceProvider.serviceprovidercode);
    //             }
    //
    //             // 平台枚举
    //             var cidEnum = serviceProvider.cid.ToString().ToEnum<CIDEnum>();
    //             
    //             if (exhibitDic.ContainsKey(cidEnum))
    //             {
    //                 exhibitDic[cidEnum].Add(exhibitItem);
    //             }
    //             else
    //             {
    //                 exhibitDic.Add(cidEnum, [exhibitItem]);
    //             }
    //         }
    //         
    //         ruleItem.FareTypes = fareTypes;
    //         ruleItem.FareTypesDic = faretypeDic;
    //         ruleItem.SPCode = spCodes;
    //         ruleItem.ExhibitDic = exhibitDic;   
    //     }
    //
    //
    //     return policySysRuleInfoList;
    // }


    /// <summary>
    /// 根据运价类型 匹配运价字典
    /// </summary>
    /// <param name="fareTypes"></param>
    /// <returns></returns>
    private Dictionary<CIDEnum, List<PolicyFareTypeEnum>> GetFareTypesDic(List<string> fareTypes)
    {
        var faretypeDic = new Dictionary<CIDEnum, List<PolicyFareTypeEnum>>();
        foreach (var fareTypeItem in fareTypes)
        {
            var result = fareTypeItem.ToEnum<PolicyFareTypeEnum>();
            // 这里实际上就是利用展位 确认OTA平台
            var cidEnum = GetPolicyFareType(result);
            if (faretypeDic.ContainsKey(cidEnum))
            {
                faretypeDic[cidEnum].Add(result);
            }
            else
            {
                faretypeDic.Add(cidEnum, [result]);
            }
        }

        return faretypeDic;
    }

    /// <summary>
    /// 解析运价类型
    /// </summary>
    /// <param name="ruleItem"></param>
    /// <returns></returns>
    private List<string> GetfaretFareTypes(PolicySysRuleInfoDto ruleItem)
    {
        var fareTypes = new List<string>();
        //运价字典
        // faretypeDic = new Dictionary<CIDEnum, List<PolicyFareTypeEnum>>();
        if (!string.IsNullOrWhiteSpace(ruleItem.FlightFareType))
        {
            fareTypes = ruleItem.FlightFareType
                .Split([",", "\n", "\r"], StringSplitOptions.RemoveEmptyEntries).ToList();
        }

        return fareTypes;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="taskItemRuleId"></param>
    /// <param name="status"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public Task UpdateStatusAsync(long taskItemRuleId, int status)
    {
        throw new NotImplementedException();
    }

    private CIDEnum GetPolicyFareType(PolicyFareTypeEnum policyFareType)
    {
        // 1. 获取枚举值的字段信息
        var fieldInfo = policyFareType.GetType().GetField(policyFareType.ToString());

        // 2. 获取 PolicyFareTypeAttribute 特性并确保存在
        var attribute = fieldInfo?.GetCustomAttributes(typeof(PolicyFareTypeAttribute), false)
            .OfType<PolicyFareTypeAttribute>()
            .FirstOrDefault();

        // 3. 返回 CID 属性值，如果没有找到特性，则返回默认值
        return attribute?.CID ?? default;
    }
}